from django.shortcuts import render, redirect

# Create your views here.
from django.views import View
from QQLoginTool.QQtool import OAuthQQ
from django.conf import settings
from django import http
import logging
from django.contrib.auth import login
import re

from django_redis import get_redis_connection

from users.models import User
from meiduo_mall.utils.response_code import RETCODE
from .models import OAuthQQUser
from .utils import generate_openid_signature, check_openid_signature
from carts.utils import merge_cart_cookie_to_redis

logger = logging.getLogger('django')


class OAuthURLView(View):

    def get(self, request):
        # 获取查询参数中next参数‘提取来源’
        next = request.GET.get('next', '/')
        # 创建oauthQQ对象
        oauth = OAuthQQ(
            client_id=settings.QQ_CLIENT_ID,
            client_secret=settings.QQ_CLIENT_SECRET,
            redirect_uri=settings.QQ_REDIRECT_URI,
            state=next,
        )

        # 调用SDK中get_qq_url方法得到凭借号的qq登陆url

        login_url = oauth.get_qq_url()
        # 响应
        print(login_url)
        # return http.JsonResponse({'code': RETCODE.OK, 'errmsg':"OK", 'login_url':login_url})
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'login_url': login_url})


class OAuthUserView(View):

    # QQ认证回调
    def get(self, request):
        print(999999)
        # 获取查询参数中的code
        code = request.GET.get('code')

        # 判断code是否获取到了
        if code is None:
            return http.HttpResponseForbidden("缺少code")
        # 创建OAuthQQ对象
        oauth = OAuthQQ(
            client_id=settings.QQ_CLIENT_ID,
            client_secret=settings.QQ_CLIENT_SECRET,
            redirect_uri=settings.QQ_REDIRECT_URI,

        )
        try:
            # 通过code获取access_token
            access_token = oauth.get_access_token(code)

            # 通过access_token获取openid
            openid = oauth.get_open_id(access_token)
        except Exception as er:
            logger.error(er)
            return http.HttpResponseServerError('QQ登陆失败')
        print(9999)
        try:
            # 向数据库中查询openid
            oauth_model = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 如果查询不到openid说明未绑定用户，把openid和meiduo用户绑定
            content = {
                'openid': generate_openid_signature(openid)
            }
            return render(request, 'oauth_callback.html', content)
        else:
            # 如果查询到了openid说明是已经绑定用户，直接登陆成功
            user = oauth_model.user
            login(request, user)
            response = redirect(request.GET.get('state') or '/')
            # 登录时合并购物车
            merge_cart_cookie_to_redis(request, response)
            response.set_cookie('username', user.username, max_age=settings.SESSION_COOKIE_AGE)
            return response

    def post(self, request):
        # 接收请体的表单数据 POST
        query_dict = request.POST
        mobile = query_dict.get('mobile')
        password = query_dict.get('password')
        sms_code_client = query_dict.get('sms_code')
        openid = query_dict.get('openid')
        # 校验
        if all([mobile, password, sms_code_client, openid]) is False:
            return http.HttpResponseForbidden('缺少必要参数')
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('请输入正确的手机号')
        if not re.match(r'^[0-9a-zA-Z]{8,20}$', password):
            return http.HttpResponseForbidden('请输入有效的密码')
        redis_conn = get_redis_connection('verify_code')
        sms_code_server = redis_conn.get('sms_%s' % mobile)
        redis_conn.delete('sms_code_%s' % mobile)
        if sms_code_server is None:
            return http.HttpResponseForbidden('短信验证码以过期')
        if sms_code_client != sms_code_server.decode():
            return http.HttpResponseForbidden('输入的验证码有误')

        try:
            # 利用手机号查询user表,如果查询到用户,说明是老用户
            user = User.objects.get(mobile=mobile)
            # 如果是老用户，再校验密码是否正确
            if user.check_password(password) is False:
                return render(request, 'oauth_callback.html', {'account_reemsg': '用户名或在密码错误'})
        except User.DoesNotExist:
            # 如果使用手机号查询不到user,说明是新用户
            # 新用户就create_user 方法创建用户
            user = User.objects.create_user(username=mobile, password=password, mobile=mobile)

        # 对openid进行解密
        print(openid)
        openid = check_openid_signature(openid)
        print(openid)
        if openid is None:
            return http.HttpResponseForbidden('openid无效')
        # 新老用户绑定openid
        OAuthQQUser.objects.create(user=user, openid=openid)
        # 登录成功后要做的事情
        login(request, user)
        response = redirect(request.GET.get('state') or '/')
        response.set_cookie('username', user.username, max_age=settings.SESSION_COOKIE_AGE)
        return response
